﻿/**
 * Created by xjchen on 2020-03-03.
 * */

#ifndef MIDDLEWARE_APPLICATION_H
#define MIDDLEWARE_APPLICATION_H


#include "IAppDelegate.h"
#include "BaseObject.h"
#include "AutoDetectWriter.h"
#include "Function.h"
#include "InterfaceInfo.h"
#include <vector>
#include <unordered_map>
#include <map>
#include <utility>

#define REGISTER_SINGLE_CLASS(a) do{Application::shareInstance()->registerClass(STRINGIFY(a), CONCATENATE(create, a), CONCATENATE(destroy, a));}while(0)
#define REGISTER_SINGLE_INSTANCE(a) do{Application::shareInstance()->registerInstance(STRINGIFY(a), typeid(a).name(), a);}while(0)
#define DISABLE_SINGLE_INSTANCE(a) do{Application::shareInstance()->disableInstance(a);}while(0)

#define REGISTER_RUNTIME_LOADED_CLASSES(...)  FOR_EACH(REGISTER_SINGLE_CLASS, __VA_ARGS__)
#define REGISTER_INSTANCES(...)  FOR_EACH(REGISTER_SINGLE_INSTANCE, __VA_ARGS__)
#define disable_instances(...)  FOR_EACH(DISABLE_SINGLE_INSTANCE, __VA_ARGS__)

// should be used in AppDelegate::onConfigure()
#define REGISTER_FUNCTION(a) do{Application::shareInstance()->registerFunction(STRINGIFY(a), (void *)a);}while(0)
#define REGISTER_FUNCTIONS(...) FOR_EACH(REGISTER_FUNCTION, __VA_ARGS__)

typedef BaseObject *(*create_t)();

typedef void (destroy_t(BaseObject *));

enum class AppState {
    Init = 1,	//初始态,应用组件已完成加载，尚未初始化
    Standby = 2,//等待态	完成应用组件初始化，等待控制信息或指令
    LocalRun = 3,//运行态	应用组件进行业务逻辑处理
    Failure = 4,//故障态	应用组件运行出现异常，等待干预
    AutoDiag = 5,//自动诊断态	应用组件对自身运行状态进行诊断，并报告结果
    InterDiag = 6,//交互诊断态	应用组件等待外部控制信息或指令，配合完成诊断
    System = 7,//重置态	应用组件接受外部控制信息或指令进行重置，可用于更新升级
    Halt = 8,//停止态	应用组件退出
};

// AppState到字符串的映射
extern const std::map<AppState, std::string> APPSTATE_STRMAP;

class Application : public BaseObject {
public:
    ~Application();

    static Application *shareInstance();

    int launch(IAppDelegate *appDelegate, int argc, char **argv);

    int runInThread(void *entry(void *), void *params, int priority, int stackSize);

	void registerClass(std::string clsName, create_t create, destroy_t *destroy);

    void registerInstance(std::string instanceName, std::string typeName, void *ptr);

    void disableInstance(void *ptr);

    void registerFunction(std::string functionName, void *ptr);

    TaskModule *findTaskModule(std::string moduleName);

    DeviceReader *findReader(const std::string &readerName);

    DeviceWriter *findWriter(const std::string &writerName);

    Function *findFunction(const std::string &functionName);

    std::vector<TaskModule *> &getAllTaskModules();

    std::vector<DeviceReader *> &getAllReaders();

    std::vector<DeviceWriter *> &getAllWriters();

    std::unordered_map<std::string, Function *> &getAllFunctions();

    int broadcast(char *str);

    std::unordered_map<std::string, AutoDetectWriter *> pendingWriters;
    bool isStop = false;
    bool configSave = false;

	/** 软雷规范相关内容 */
    using InterfaceCallback = void (*)(void *, std::vector<InterfaceInfo>&);
    //获取软雷 hostid,instance—Id,JCKJ-hostID信息
    std::pair<std::string,std::string> GetRlHostIDs();
    // 获取Component.xml中的参数配置
    std::vector<std::map<std::string, std::string>> getRlReaderCfg(std::string inputName);
	std::vector<std::map<std::string, std::string>> getRlWriterCfg(std::string outputName);
	std::map<std::string, std::string> getRlConfigParam(std::string paramName);

    AppState getAppState();
    std::map<std::string, std::string> *getFailureInfo();
	bool tryEnterAppState(AppState newState, char instructionType);
	bool enterAppState(AppState newState);
    void reportFailure(std::string objName, std::string failureMsg);
    void queryInterface(std::string fullName, InterfaceCallback fun, void *param);
    void queryOutputInterfaceInfo(std::string ifName, std::string dataStruct, 
                                  InterfaceCallback fun, void *param);
    void provideInputInterfaceInfo(std::string ifName, std::string dataStruct, 
                                   std::string protocol, std::string ip, int port);
private:
    friend class Scheduler;

    /** disable the default constructor. */
    Application();

    void autoDetectInterfaceConnect();

    void recursivelyPassOrigReaderToNext(TaskModule *pModule);

    void findMostOrigReaderForEachTaskModule();

    std::vector<TaskModule *> allModules;
    std::vector<DeviceReader *> allReaders;
    std::vector<DeviceWriter *> allWriters;
    std::unordered_map<std::string, Function *> allFunctions;
    device_config_t *config = 0;
    const char *configFile = 0;
    char *configFileForSave = 0;
    char *configFileForRecovery = 0;
    bool configRecovery = false;
    std::vector<TaskModule *> markQueue;
    std::vector<char *> buffers;

	/** 软雷规范相关内容 */
	AppState state;
	std::map<std::string, std::string> failureInfo; //各模块异常信息
};

#endif /** MIDDLEWARE_APPLICATION_H */
